package pl.edu.agh.gronoMining.frequentSubgraphFinder;

import java.io.File;
import java.text.ParseException;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import pl.edu.agh.gronoMining.frequentSubgraphFinder.frequentSearcher.Miner;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.graph.Graph;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.parsers.graph.ExtendedLineGraphParser;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.parsers.graph.GraphParser;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.parsers.strategy.StrategyParser;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.parsers.strategy.StrategyParserImpl;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.strategy.Strategy;

public class Main {
	
	private static final String LOGGER_PROP_FILE = "resources/logger.properties.xml";
	
	private static final Set<String> possibleArgsSet = new HashSet<String>();
	
	private static final Set<String> neceseryArgsSet = new HashSet<String>();
	
	static {
		possibleArgsSet.add("inputGraph");
		possibleArgsSet.add("outputGraph");
		possibleArgsSet.add("strategy");
		possibleArgsSet.add("minimumFrequencies");
		possibleArgsSet.add("isGraphTree");
		
		neceseryArgsSet.add("inputGraph");
		neceseryArgsSet.add("strategy");
		neceseryArgsSet.add("minimumFrequencies");
	}

	private static Properties parseArgs(String[] args) throws ParseException {
		Properties p = new Properties();
		for (String arg : args) {
			String[] argParts = arg.split("=");
			if (argParts.length != 2) {
				throw new ParseException("wrong argument "+arg, 1);
			} else if (argParts[0].charAt(0) != '-') {
				throw new ParseException("wrong argument "+arg, 1);
			} else {
				String key = argParts[0].substring(1);
				String value = argParts[1];
				if (possibleArgsSet.contains(key))
					p.setProperty(key, value);
				else
					throw new ParseException("wrong argument "+arg, 1);
			}
		}
		return p;
	}
	
	private static Properties updateAdgs(Properties p) throws ParseException {
		
		for (String neceseryKey : neceseryArgsSet) {
			if (p.getProperty(neceseryKey) == null)
				throw new ParseException("you have to specify argument "+neceseryKey, 1);
		}
		
		if (p.getProperty("outputGraph") == null) {
			p.setProperty("outputGraph", p.getProperty("inputGraph") + ".out");
		}
		
		if (p.getProperty("isGraphTree") == null) {
			p.setProperty("isGraphTree", "false");
		}
		
		return p;
	}
	
	public static void main(String[] args) {
		
		//System.out.println("aaa");
		
		DOMConfigurator.configure(LOGGER_PROP_FILE);
		Logger logger = Logger.getLogger(Main.class);
		logger.info("loger inicialized");
		
		//System.out.println("bbb");
		
		try {
			
			
			Properties properties = parseArgs(args);
			properties = updateAdgs(properties);
			
			logger.info("properties readed");
			
			StrategyParser strategyParser = new StrategyParserImpl();
			Strategy strategy = strategyParser.parse(new File(properties.getProperty("strategy")));
			
			logger.info("strategy parsed");
			
			GraphParser graphParser = new ExtendedLineGraphParser();
			Graph inputGraph = graphParser.parse(new File(properties.getProperty("inputGraph")));
			
			logger.info("graph parsed");
			
			Miner subgraphMiner = new Miner(inputGraph, strategy, properties);
			
			logger.info("start mining");
			
			Set<Graph> frequentSubgraphs = subgraphMiner.startMining();
			
			logger.info("end mining - result is " + frequentSubgraphs.size() + " graphs");
			
			graphParser.serializeToFile(frequentSubgraphs, new File(properties.getProperty("outputGraph")));
			
			logger.info("result serialized");
			
		} catch (ParseException e) {
			System.err.println(e.getMessage());
		}

	}
	
}
